gtkmediafile: Only unmap the GstVideoFrame in the GBytes destroy notify
authorSebastian Dröge <sebastian@centricular.com>
Sat, 26 Dec 2020 12:26:23 +0000 (14:26 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Sat, 26 Dec 2020 12:26:23 +0000 (14:26 +0200)
The memory pointed to by GstVideoFrame::plane_data becomes invalid after
unmapping causing the GBytes to point at some random memory if the
unmapping is not deferred until its destroy notify.

When the GStreamer buffer is backed by normal system memory this is not
a problem but if it is backed by e.g. an OpenGL texture, dmabuf or some
other hardware-specific memory this will otherwise cause interesting
problems.

modules/media/gtkgstsink.c

index 4959bb86f8d46d39ba56c6bc39b3f229a18f186f..e923ea88d6ba768ff7cbe6e9b01ba88eef880860 100644 (file)
@@ -111,6 +111,13 @@ gtk_gst_memory_format_from_video (GstVideoFormat format)
   }
 }
 
+static void
+video_frame_free (GstVideoFrame *frame)
+{
+  gst_video_frame_unmap (frame);
+  g_free (frame);
+}
+
 static GdkTexture *
 gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
                                   GstBuffer  *buffer)
@@ -124,15 +131,14 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
 
   bytes = g_bytes_new_with_free_func (frame.data[0],
                                       frame.info.width * frame.info.stride[0],
-                                      (GDestroyNotify) gst_buffer_unref,
-                                      gst_buffer_ref (buffer));
+                                      (GDestroyNotify) video_frame_free,
+                                      g_memdup (&frame, sizeof (frame)));
   texture = gdk_memory_texture_new (frame.info.width,
                                     frame.info.height,
                                     gtk_gst_memory_format_from_video (GST_VIDEO_FRAME_FORMAT (&frame)),
                                     bytes,
                                     frame.info.stride[0]);
   g_bytes_unref (bytes);
-  gst_video_frame_unmap (&frame);
 
   return texture;
 }